﻿using SmartCA.Infrastructure.DomainBase;
using SmartCA.Infrastructure.RepositoryFramework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace SmartCA.Infrastructure
{
    public class UnitOfWork : IUnitOfWork
    {
        private Dictionary<EntityBase, IUnitOfWorkRepository> addedEntities;
        private Dictionary<EntityBase, IUnitOfWorkRepository> changedEntities;
        private Dictionary<EntityBase, IUnitOfWorkRepository> deletedEntities;

        public UnitOfWork()
        {
            addedEntities = new Dictionary<EntityBase, IUnitOfWorkRepository>();
            changedEntities = new Dictionary<EntityBase, IUnitOfWorkRepository>();
            deletedEntities = new Dictionary<EntityBase, IUnitOfWorkRepository>();
        }

        #region IUnitOfWork Members
       
        public void RegisterAdded(EntityBase entity, IUnitOfWorkRepository repository)
        {
            this.addedEntities.Add(entity, repository);
        }

        public void RegisterChanged(EntityBase entity, IUnitOfWorkRepository repository)
        {
            this.changedEntities.Add(entity, repository);
        }

        public void RegisterRemoved(EntityBase entity, IUnitOfWorkRepository repository)
        {
            this.deletedEntities.Add(entity, repository);
        }

        public void Commit()
        {
            using (TransactionScope scope = new TransactionScope())
            {
                foreach (EntityBase entity in deletedEntities.Keys)
                {
                    this.deletedEntities[entity].PersistDeletedItem(entity);                    
                }

                foreach (EntityBase entity in addedEntities.Keys)
                {
                    this.addedEntities[entity].PersistNewItem(entity);                    
                }

                foreach (EntityBase entity in changedEntities.Keys)
                {
                    this.changedEntities[entity].PersistUpdateItem(entity);                    
                }

                scope.Complete();
            }
           
            this.deletedEntities.Clear();
            this.addedEntities.Clear();
            this.changedEntities.Clear();
        }

        #endregion
    }
}
